#include "rust_cxx_demo/src/rscxx.rs.h"

#include "rust_cxx_demo/librscxx/rscxx.h"
#include <variant>
#include <algorithm>
#include <functional>
#include <set>
#include <string>
#include <cstdint>
#include <unordered_map>

#include "cmakecxx.h"


RsCxxCls::RsCxxCls() {
    test_str = "test RsCxxCls";
    test_n = 3.1415926;
    array = {"aa", "bb"};
}

RsCxxCls::~RsCxxCls() {}


std::map<int, std::string> tags;


bool RsCxxCls::isNull() const { return false; }
bool RsCxxCls::isString() const { return false; }

double RsCxxCls::getNumber() const { return test_n; }

std::unique_ptr<std::string> RsCxxCls::getString() const {
    return std::make_unique<std::string>(test_str);
}
// std::vector<std::string> &RsCxxCls::getVector() const { return array; }

int RsCxxCls::put(MultiBuf &buf) const {
    std::string contents;
    while (true)
    {
        auto chunk = next_chunk(buf);
        if (chunk.size() == 0) {
            break;
        }
        contents.append(reinterpret_cast<const char *>(chunk.data()), chunk.size());
    }

    CmakeCxx cxx;
    cxx.SetName("rscxx test");
    cxx.ShowName();
    
    auto id = std::hash<std::string>{}(contents);
    return (id & 0xffffff);
}

void RsCxxCls::tag(int id, rust::Str tag) const {
    tags[id] = std::string(tag);
}

BlobMetadata RsCxxCls::metadata(int id) const {
    BlobMetadata data{};
    auto blob = tags.find(id);
    if (blob != tags.end()) {
        data.size = blob->second.size();
        data.tags.emplace_back(blob->second);
        //std::for_each(blob->second.cbegin(), blob->second.cend(), [&](auto &t) { data.tags.emplace_back(t);});
    }

    return data;
}


std::unique_ptr<RsCxxCls> getRsCxx() { return std::make_unique<RsCxxCls>(); }
